package us.gaaoc.framework.webapp.security;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import us.gaaoc.framework.dao.ModelFacade;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.Roles;

/**
 * Spring security user details service which looks up
 * authentication information from the GAJE database.
 * @author artripa
 *
 */
public class GajeUserDetailsService implements UserDetailsService{

	@Autowired
	ModelFacade facade;
	
	@Transactional
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		
		if(username == null || username.trim().equalsIgnoreCase(""))
		{
			throw new UsernameNotFoundException("No username given!");
		}
		
		Person p = facade.getPersonByUserName(username);
		
		if(p == null)
		{
			throw new UsernameNotFoundException("User " + username + " not found");		
		}
		return new PersonUserDetails(p);
	}
	
}

/**
 * User details object which maps the GAJE Person object
 * with the UserDetails spring security interface.
 * @author artripa
 *
 */
class PersonUserDetails implements UserDetails
{

	private static final long serialVersionUID = 1L;
	Collection<GrantedAuthority> auths;
	String password;
	String username;
	
	public PersonUserDetails(Person p) {
		username = p.getUserId();
		password = p.getPassword();
		
		auths = new ArrayList<GrantedAuthority>();
		auths.add(new GrantedAuthorityImpl("ROLE_USER"));
		auths.add(new GrantedAuthorityImpl("ROLE_DCSS"));		
		
		for(Roles r : p.getRoles())
		{
			auths.add(new GrantedAuthorityImpl("ROLE_" + r.getRole().toUpperCase()));
		}		
	}
	
	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		return auths;
	}

	@Override
	public String getPassword() {
		return password;
	}

	@Override
	public String getUsername() {
		return username;
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		return true;
	}
	
}